package cn.jupiter.json;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.jupiter.db.DbUtils;

import java.sql.Types;
/**
 * ���ת��Ϊjson����
 * @author pizhenhua@gmail.com
 *
 */
public class ResultSetJson{
	protected final Log log = LogFactory.getLog(ResultSetJson.class);
	private int total;
	private int page=1;
	private int num;
	private ResultSet resultSet;
	private Statement stmt;
	private Connection conn=null;
	private RestResource restResource=null;
	private String JSON_TYPE=JSON_TYPE_2;
	public static String JSON_TYPE_1="json1";
	public static String JSON_TYPE_2="json2";
	StringBuilder json=new StringBuilder("");
	
	public ResultSetJson(Connection conn,RestResource restResource){
		this.conn=conn;
		String sql,sql2=null;
	//	this.resultSet=resultSet;
		//������sql����sqlִ��
		if(null!=restResource.getSql()){
			 sql=restResource.getSql();
			 sql2="select count(*) from ("+sql+") "+DbUtils.TABLE_PREFIX+restResource.getResouce();
		}
		else{
			 sql="select * from "+restResource.getResouce()+" where id="+restResource.getId();
			  sql2="select count(id) from ("+sql+") "+DbUtils.TABLE_PREFIX+restResource.getResouce();
		}
		
		try {
			Statement stmt = conn.createStatement();
			log.debug("sql:"+sql2);
			resultSet=stmt.executeQuery(sql2);
			if(resultSet.next()){
				this.total=resultSet.getInt(1);
			}	
			log.debug("sql:"+sql);
			resultSet=stmt.executeQuery(sql);
			json.append("{\"total\":");
			json.append(total);
			json.append(",\"page\":");
			json.append(page);
			//json.append(",\"num\":");
			//json.append(num);
			json.append(",\"rows\":");
			getReslutSetJson(resultSet);
			json.append("}");
			stmt.close();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	private void getReslutSetJson2(ResultSet resultSet){
		json.append("[");
		
			try {
				while(resultSet.next()){
					json.append("{\"id\":");
					json.append(resultSet.getInt("id"));
					json.append(",\"data\":[");
					for(int i=1;i<=resultSet.getMetaData().getColumnCount();i++){
						if(resultSet.getMetaData().getColumnType(i)==Types.INTEGER){
							json.append(resultSet.getInt(i));
							if(i<resultSet.getMetaData().getColumnCount()){
								json.append(",");
							}
						}
						if(resultSet.getMetaData().getColumnType(i)==Types.DOUBLE){
							json.append(resultSet.getDouble(i));
							if(i<resultSet.getMetaData().getColumnCount()){
								json.append(",");
							}
						}
						if(resultSet.getMetaData().getColumnType(i)==Types.NUMERIC){
							json.append(resultSet.getString(i));
							if(i<resultSet.getMetaData().getColumnCount()){
								json.append(",");
							}
							
						}
						if(resultSet.getMetaData().getColumnType(i)==Types.VARCHAR){
							json.append("\""+resultSet.getString(i));
							if(i<resultSet.getMetaData().getColumnCount()){
								json.append("\",");
							}
							else{
								json.append("\"");
							}
						}
						
					}
					json.append("]},");
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			json.deleteCharAt(json.length()-1);
			//json.delete( json.length()-1);

			
			json.append("]");
			
			json.append(",\"columns\":");
			json.append("\"");
			
	
			try {
				for(int i=1;i<=resultSet.getMetaData().getColumnCount();i++){
					json.append(resultSet.getMetaData().getColumnLabel(i)+",");
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			json.deleteCharAt(json.length()-1);
			json.append("\"");
			

	}
	/**
	 * ���json
	 * ��ʽ1��
	 * 
	 * ��ʽ2��
	 * 
	 * @param resultSet
	 */
	private void getReslutSetJson(ResultSet resultSet){
		if(ResultSetJson.JSON_TYPE_1.equals(this.getJSON_TYPE())){
			this.getReslutSetJson1(resultSet);
		}
		if(ResultSetJson.JSON_TYPE_2.equals(this.getJSON_TYPE())){
			this.getReslutSetJson2(resultSet);
		}
	}
	private void getReslutSetJson1(ResultSet resultSet){
		json.append("[{");
		try {
			while(resultSet.next()){
				for(int i=1;i<=resultSet.getMetaData().getColumnCount();i++){
					json.append("\"");
					json.append(resultSet.getMetaData().getColumnLabel(i));
					json.append("\":");
					
					if(resultSet.getMetaData().getColumnType(i)==Types.INTEGER){
						json.append(resultSet.getInt(i));
						if(i<resultSet.getMetaData().getColumnCount()){
							json.append(",");
						}
					}
					if(resultSet.getMetaData().getColumnType(i)==Types.DOUBLE){
						json.append(resultSet.getDouble(i));
						if(i<resultSet.getMetaData().getColumnCount()){
							json.append(",");
						}
					}
					if(resultSet.getMetaData().getColumnType(i)==Types.NUMERIC){
						json.append(resultSet.getString(i));
						if(i<resultSet.getMetaData().getColumnCount()){
							json.append(",");
						}
						
					}
					if(resultSet.getMetaData().getColumnType(i)==Types.VARCHAR){
						json.append("\""+resultSet.getString(i));
						if(i<resultSet.getMetaData().getColumnCount()){
							json.append("\",");
						}
						else{
							json.append("\"");
						}
					}
					//System.out.println(resultSet.getMetaData().getColumnType(i));
					//json.append(resultSet.get);
					
				}
				json.append("},{");
				
				
			}
			json.delete(json.length()-4, json.length());
			json.append("\"}]");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//private StringBuilder json = new StringBuilder(""); 
	public String toJson(){

	//	rowSet.getMetaData().get
		return json.toString();
	}

	
	public void setTotal(int total) {
		this.total = total; 
	}

	public void setPage(int page) {
		this.page = page; 
	}

	public void setNum(int num) {
		this.num = num; 
	}



	public ResultSet getResultSet() {
		return resultSet;
	}


	public void setResultSet(ResultSet resultSet) {
		this.resultSet = resultSet;
	}


	public int getTotal() {
		return (this.total); 
	}

	public int getPage() {
		return (this.page); 
	}

	public int getNum() {
		return (this.num); 
	}


	public Statement getStmt() {
		return stmt;
	}


	public void setStmt(Statement stmt) {
		this.stmt = stmt;
	}
	/**
	 * �������json��ʽ����
	 * @return
	 */
	public String getJSON_TYPE() {
		return JSON_TYPE;
	}
	public void setJSON_TYPE(String json_type) {
		JSON_TYPE = json_type;
	}


}
